package cn.template.controllers;

import cn.template.common.JwtTokenUtil;
import cn.template.models.common.JwtRequest;
import cn.template.models.common.JwtResponse;
import cn.template.models.common.JwtUser;
import cn.template.models.exceptions.AppException;
import cn.template.services.UserService;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Objects;

@RestController
@RequestMapping("/api/authenticate")
@Api(value = "用户认证接口")
public class JwtAuthenticationController extends BaseController<UserService> {

	private final AuthenticationManager authenticationManager;

	private final JwtTokenUtil jwtTokenUtil;


	public JwtAuthenticationController(AuthenticationManager authenticationManager, JwtTokenUtil jwtTokenUtil, UserService userService) {
		this.authenticationManager = authenticationManager;
		this.jwtTokenUtil = jwtTokenUtil;
		this.service = userService;
	}

	@PostMapping("")
	@Operation(summary = "login", description = "分页获取企业列表")
	public ResponseEntity<?> authenticate(@RequestBody JwtRequest authenticationRequest) {
		authenticateInner(authenticationRequest.getUsername(), authenticationRequest.getPassword());

		final JwtUser userDetails = service.getByUsername(authenticationRequest.getUsername());
		userDetails.setPassword(null);
		final String token = jwtTokenUtil.generateToken(userDetails);
		return ResponseEntity.ok(new JwtResponse(token, userDetails));
	}

	@PostMapping(value = "/renew-token")
	@Operation(summary = "renew", description = "分页获取企业列表")
	public ResponseEntity<?> renewAuthenticationToken() {
		final JwtUser userDetails = getUser();
		final String token = jwtTokenUtil.generateToken(userDetails);
		return ResponseEntity.ok(token);
	}

	private void authenticateInner(String username, String password) {
		Objects.requireNonNull(username);
		Objects.requireNonNull(password);
		try {
			authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
		} catch (DisabledException e) {
			throw new AppException("USER_DISABLED", HttpStatus.FORBIDDEN);
		} catch (BadCredentialsException e) {
			throw new AppException("INVALID_CREDENTIALS", HttpStatus.BAD_REQUEST);
		} catch (Exception e) {
			throw new AppException("INVALID_USERNAME_OR_PASSWORD", HttpStatus.BAD_REQUEST);
		}
	}
}
